package algorithms

import (
	"context"
	"fmt"
	"runtime"
	"strings"
	"sync"
	"time"
)

// BenchmarkSuite 性能基准测试套件
type BenchmarkSuite struct {
	results map[string]*BenchmarkResult
	mu      sync.RWMutex
}

// BenchmarkResult 基准测试结果
type BenchmarkResult struct {
	Name           string
	Iterations     int
	TotalDuration  time.Duration
	AvgDuration    time.Duration
	MinDuration    time.Duration
	MaxDuration    time.Duration
	MemoryUsage    int64
	Allocations    int64
	Throughput     float64
	Timestamp      time.Time
}

// NewBenchmarkSuite 创建基准测试套件
func NewBenchmarkSuite() *BenchmarkSuite {
	return &BenchmarkSuite{
		results: make(map[string]*BenchmarkResult),
	}
}

// RunBenchmark 运行基准测试
func (bs *BenchmarkSuite) RunBenchmark(name string, iterations int, fn func()) *BenchmarkResult {
	var totalDuration time.Duration
	var minDuration = time.Duration(int64(^uint64(0) >> 1)) // 最大值
	var maxDuration time.Duration

	// 获取初始内存统计
	var m1, m2 runtime.MemStats
	runtime.GC()
	runtime.ReadMemStats(&m1)

	// 执行基准测试
	for i := 0; i < iterations; i++ {
		start := time.Now()
		fn()
		duration := time.Since(start)

		totalDuration += duration
		if duration < minDuration {
			minDuration = duration
		}
		if duration > maxDuration {
			maxDuration = duration
		}
	}

	// 获取最终内存统计
	runtime.GC()
	runtime.ReadMemStats(&m2)

	// 计算结果
	avgDuration := totalDuration / time.Duration(iterations)
	memoryUsage := int64(m2.TotalAlloc - m1.TotalAlloc)
	allocations := int64(m2.Mallocs - m1.Mallocs)
	throughput := float64(iterations) / totalDuration.Seconds()

	result := &BenchmarkResult{
		Name:           name,
		Iterations:     iterations,
		TotalDuration:  totalDuration,
		AvgDuration:    avgDuration,
		MinDuration:    minDuration,
		MaxDuration:    maxDuration,
		MemoryUsage:    memoryUsage,
		Allocations:    allocations,
		Throughput:     throughput,
		Timestamp:      time.Now(),
	}

	// 存储结果
	bs.mu.Lock()
	bs.results[name] = result
	bs.mu.Unlock()

	return result
}

// CompareBenchmarks 比较两个基准测试结果
func (bs *BenchmarkSuite) CompareBenchmarks(name1, name2 string) *BenchmarkComparison {
	bs.mu.RLock()
	result1, exists1 := bs.results[name1]
	result2, exists2 := bs.results[name2]
	bs.mu.RUnlock()

	if !exists1 || !exists2 {
		return nil
	}

	return &BenchmarkComparison{
		Baseline:        result1,
		Optimized:       result2,
		SpeedImprovement: float64(result1.AvgDuration) / float64(result2.AvgDuration),
		MemoryReduction:  float64(result1.MemoryUsage-result2.MemoryUsage) / float64(result1.MemoryUsage) * 100,
		ThroughputGain:   (result2.Throughput - result1.Throughput) / result1.Throughput * 100,
	}
}

// BenchmarkComparison 基准测试比较结果
type BenchmarkComparison struct {
	Baseline         *BenchmarkResult
	Optimized        *BenchmarkResult
	SpeedImprovement float64 // 速度提升倍数
	MemoryReduction  float64 // 内存减少百分比
	ThroughputGain   float64 // 吞吐量提升百分比
}

// PrintResults 打印基准测试结果
func (bs *BenchmarkSuite) PrintResults() {
	bs.mu.RLock()
	defer bs.mu.RUnlock()

	fmt.Println("\n=== 性能基准测试结果 ===")
	fmt.Printf("%-20s %-10s %-15s %-15s %-15s %-12s %-12s %-15s\n",
		"测试名称", "迭代次数", "平均耗时", "最小耗时", "最大耗时", "内存使用", "分配次数", "吞吐量(ops/s)")
	fmt.Println(strings.Repeat("-", 120))

	for _, result := range bs.results {
		fmt.Printf("%-20s %-10d %-15s %-15s %-15s %-12s %-12d %-15.2f\n",
			result.Name,
			result.Iterations,
			result.AvgDuration.String(),
			result.MinDuration.String(),
			result.MaxDuration.String(),
			formatBytes(result.MemoryUsage),
			result.Allocations,
			result.Throughput,
		)
	}
}

// PrintComparison 打印比较结果
func (comp *BenchmarkComparison) PrintComparison() {
	if comp == nil {
		fmt.Println("无效的比较结果")
		return
	}

	fmt.Println("\n=== 性能对比分析 ===")
	fmt.Printf("基准测试: %s\n", comp.Baseline.Name)
	fmt.Printf("优化测试: %s\n", comp.Optimized.Name)
	fmt.Printf("速度提升: %.2fx\n", comp.SpeedImprovement)
	fmt.Printf("内存减少: %.2f%%\n", comp.MemoryReduction)
	fmt.Printf("吞吐量提升: %.2f%%\n", comp.ThroughputGain)

	if comp.SpeedImprovement > 1.1 {
		fmt.Println("✅ 性能显著提升")
	} else if comp.SpeedImprovement > 1.0 {
		fmt.Println("✅ 性能轻微提升")
	} else {
		fmt.Println("❌ 性能未提升")
	}
}

// PerformanceProfiler 性能分析器
type PerformanceProfiler struct {
	samples []ProfileSample
	mu      sync.Mutex
}

// ProfileSample 性能采样
type ProfileSample struct {
	Timestamp   time.Time
	CPUUsage    float64
	MemoryUsage int64
	Goroutines  int
	GCPauses    time.Duration
}

// NewPerformanceProfiler 创建性能分析器
func NewPerformanceProfiler() *PerformanceProfiler {
	return &PerformanceProfiler{
		samples: make([]ProfileSample, 0),
	}
}

// StartProfiling 开始性能分析
func (pp *PerformanceProfiler) StartProfiling(interval time.Duration) chan struct{} {
	stop := make(chan struct{})

	go func() {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				pp.takeSample()
			case <-stop:
				return
			}
		}
	}()

	return stop
}

// takeSample 采集性能样本
func (pp *PerformanceProfiler) takeSample() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)

	sample := ProfileSample{
		Timestamp:   time.Now(),
		MemoryUsage: int64(m.Alloc),
		Goroutines:  runtime.NumGoroutine(),
		GCPauses:    time.Duration(m.PauseNs[(m.NumGC+255)%256]),
	}

	pp.mu.Lock()
	pp.samples = append(pp.samples, sample)
	// 保持最近1000个样本
	if len(pp.samples) > 1000 {
		pp.samples = pp.samples[1:]
	}
	pp.mu.Unlock()
}

// GetProfileSummary 获取性能分析摘要
func (pp *PerformanceProfiler) GetProfileSummary() *ProfileSummary {
	pp.mu.Lock()
	defer pp.mu.Unlock()

	if len(pp.samples) == 0 {
		return nil
	}

	var totalMemory int64
	var totalGoroutines int64
	var totalGCPauses time.Duration
	maxMemory := pp.samples[0].MemoryUsage
	maxGoroutines := pp.samples[0].Goroutines

	for _, sample := range pp.samples {
		totalMemory += sample.MemoryUsage
		totalGoroutines += int64(sample.Goroutines)
		totalGCPauses += sample.GCPauses

		if sample.MemoryUsage > maxMemory {
			maxMemory = sample.MemoryUsage
		}
		if sample.Goroutines > maxGoroutines {
			maxGoroutines = sample.Goroutines
		}
	}

	sampleCount := len(pp.samples)
	return &ProfileSummary{
		SampleCount:     sampleCount,
		AvgMemoryUsage:  totalMemory / int64(sampleCount),
		MaxMemoryUsage:  maxMemory,
		AvgGoroutines:   int(totalGoroutines / int64(sampleCount)),
		MaxGoroutines:   maxGoroutines,
		AvgGCPause:      totalGCPauses / time.Duration(sampleCount),
		Duration:        pp.samples[sampleCount-1].Timestamp.Sub(pp.samples[0].Timestamp),
	}
}

// ProfileSummary 性能分析摘要
type ProfileSummary struct {
	SampleCount     int
	AvgMemoryUsage  int64
	MaxMemoryUsage  int64
	AvgGoroutines   int
	MaxGoroutines   int
	AvgGCPause      time.Duration
	Duration        time.Duration
}

// LoadTester 负载测试器
type LoadTester struct {
	concurrency int
	duration    time.Duration
	requestRate int
}

// NewLoadTester 创建负载测试器
func NewLoadTester(concurrency int, duration time.Duration, requestRate int) *LoadTester {
	return &LoadTester{
		concurrency: concurrency,
		duration:    duration,
		requestRate: requestRate,
	}
}

// RunLoadTest 运行负载测试
func (lt *LoadTester) RunLoadTest(testFn func() error) *LoadTestResult {
	var wg sync.WaitGroup
	var mu sync.Mutex
	var totalRequests int64
	var successRequests int64
	var totalLatency time.Duration
	var minLatency = time.Duration(int64(^uint64(0) >> 1))
	var maxLatency time.Duration

	start := time.Now()
	ctx, cancel := context.WithTimeout(context.Background(), lt.duration)
	defer cancel()

	// 启动并发工作协程
	for i := 0; i < lt.concurrency; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			ticker := time.NewTicker(time.Second / time.Duration(lt.requestRate/lt.concurrency))
			defer ticker.Stop()

			for {
				select {
				case <-ctx.Done():
					return
				case <-ticker.C:
					reqStart := time.Now()
					err := testFn()
					latency := time.Since(reqStart)

					mu.Lock()
					totalRequests++
					if err == nil {
						successRequests++
					}
					totalLatency += latency
					if latency < minLatency {
						minLatency = latency
					}
					if latency > maxLatency {
						maxLatency = latency
					}
					mu.Unlock()
				}
			}
		}()
	}

	wg.Wait()
	actualDuration := time.Since(start)

	return &LoadTestResult{
		TotalRequests:   totalRequests,
		SuccessRequests: successRequests,
		FailedRequests:  totalRequests - successRequests,
		SuccessRate:     float64(successRequests) / float64(totalRequests) * 100,
		AvgLatency:      totalLatency / time.Duration(totalRequests),
		MinLatency:      minLatency,
		MaxLatency:      maxLatency,
		Throughput:      float64(totalRequests) / actualDuration.Seconds(),
		Duration:        actualDuration,
	}
}

// LoadTestResult 负载测试结果
type LoadTestResult struct {
	TotalRequests   int64
	SuccessRequests int64
	FailedRequests  int64
	SuccessRate     float64
	AvgLatency      time.Duration
	MinLatency      time.Duration
	MaxLatency      time.Duration
	Throughput      float64
	Duration        time.Duration
}